package com.example.netchat;

import java.util.ArrayList;
import java.util.List;

import android.content.ContentValues;
import android.content.Context;
import android.content.Intent;
import android.net.Uri;
import android.os.Bundle;
import android.support.v4.app.DialogFragment;
import android.support.v4.app.Fragment;
import android.support.v4.app.FragmentActivity;
import android.support.v4.app.FragmentManager;
import android.support.v4.app.FragmentPagerAdapter;
import android.support.v4.view.ViewPager;
import android.view.Menu;
import android.view.MenuItem;
import android.view.View;
import android.view.ViewGroup;
import android.widget.TabHost;
import android.widget.TabWidget;

import com.example.netchat.ContentUtils.Room;

public class MainActivity extends FragmentActivity implements
		CreateRoomDialogListener, RoomListActionListener,
		ChatFragment.ActionListener {
	private static final String ROOM_ID_EXTRA = "roomId";
	TabHost mTabHost;
	ViewPager mViewPager;
	TabsAdapter mTabsAdapter;
	private ChatFragment mChatFragment;

	@Override
	public void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);

		handleIntent(getIntent(), savedInstanceState);
	}

	@Override
	protected void onNewIntent(Intent intent) {
		super.onNewIntent(intent);

		handleIntent(intent, null);
	}

	private void handleIntent(Intent intent, Bundle savedInstanceState) {

		if (intent.getAction() == Intent.ACTION_VIEW) {
			Uri url = intent.getData();

			if (url != null) {
				List<String> segments = url.getPathSegments();

				String roomId = segments.get(segments.size() - 1);
				String roomName = url.getQueryParameter("roomName");

				startService(ChatService.createJoinRoomIntent(
						getApplicationContext(), roomId, roomName));
			}
			finish();
			return;
		} else {
			setContentView(R.layout.activity_roster);

			mTabHost = (TabHost) findViewById(android.R.id.tabhost);
			mTabHost.setup();

			mViewPager = (ViewPager) findViewById(R.id.pager);

			mTabsAdapter = new TabsAdapter(this, mTabHost, mViewPager);
			mTabsAdapter.addTab(
					mTabHost.newTabSpec("rooms").setIndicator(
							getString(R.string.rooms)), RoomListFragment.class,
					null);
			Bundle favorites_args = new Bundle();
			favorites_args.putBoolean(RoomListFragment.ARGUMENT_ONLY_FAVORITES,
					true);

			mTabsAdapter.addTab(
					mTabHost.newTabSpec("favorites").setIndicator(
							getString(R.string.favorites)),
					RoomListFragment.class, favorites_args);

			if (savedInstanceState != null) {
				mTabHost.setCurrentTabByTag(savedInstanceState.getString("tab"));
			}

			if (intent.hasExtra(ROOM_ID_EXTRA)) {
				onEnterRoomAction(getIntent().getStringExtra(ROOM_ID_EXTRA));
			}
		}
	}

	private Intent getServiceIntent() {
		return new Intent(getApplicationContext(), ChatService.class);
	}

	@Override
	protected void onResume() {
		super.onResume();
		Intent serviceIntent = getServiceIntent();
		startService(serviceIntent);
	}

	@Override
	protected void onPause() {
		super.onPause();
	}

	@Override
	public boolean onCreateOptionsMenu(Menu menu) {
		getMenuInflater().inflate(R.menu.activity_main, menu);
		return true;
	}

	@Override
	public boolean onOptionsItemSelected(MenuItem item) {
		switch (item.getItemId()) {
		case R.id.add_room:
			DialogFragment newFragment = new CreateRoomDialogFragment();
			newFragment.show(getSupportFragmentManager(), "add_buddy");
			break;
		case R.id.settings:
			startActivity(new Intent(this, SettingsActivity.class));
			break;
		}

		return super.onOptionsItemSelected(item);
	}

	public static class TabsAdapter extends FragmentPagerAdapter implements
			TabHost.OnTabChangeListener, ViewPager.OnPageChangeListener {
		private final Context mContext;
		private final TabHost mTabHost;
		private final ViewPager mViewPager;
		private final ArrayList<TabInfo> mTabs = new ArrayList<TabInfo>();

		static final class TabInfo {
			private final String tag;
			private final Class<?> clss;
			private final Bundle args;

			TabInfo(String _tag, Class<?> _class, Bundle _args) {
				tag = _tag;
				clss = _class;
				args = _args;
			}

			public String getTag() {
				return tag;
			}
		}

		static class DummyTabFactory implements TabHost.TabContentFactory {
			private final Context mContext;

			public DummyTabFactory(Context context) {
				mContext = context;
			}

			@Override
			public View createTabContent(String tag) {
				View v = new View(mContext);
				v.setMinimumWidth(0);
				v.setMinimumHeight(0);
				return v;
			}
		}

		public TabsAdapter(FragmentActivity activity, TabHost tabHost,
				ViewPager pager) {
			super(activity.getSupportFragmentManager());
			mContext = activity;
			mTabHost = tabHost;
			mViewPager = pager;
			mTabHost.setOnTabChangedListener(this);
			mViewPager.setAdapter(this);
			mViewPager.setOnPageChangeListener(this);
		}

		public void addTab(TabHost.TabSpec tabSpec, Class<?> clss, Bundle args) {
			tabSpec.setContent(new DummyTabFactory(mContext));
			String tag = tabSpec.getTag();

			TabInfo info = new TabInfo(tag, clss, args);
			mTabs.add(info);
			mTabHost.addTab(tabSpec);
			notifyDataSetChanged();
		}

		@Override
		public int getCount() {
			return mTabs.size();
		}

		@Override
		public Fragment getItem(int position) {
			TabInfo info = mTabs.get(position);
			return Fragment.instantiate(mContext, info.clss.getName(),
					info.args);
		}

		@Override
		public void onTabChanged(String tabId) {
			int position = mTabHost.getCurrentTab();
			mViewPager.setCurrentItem(position);
		}

		@Override
		public void onPageScrolled(int position, float positionOffset,
				int positionOffsetPixels) {
		}

		@Override
		public void onPageSelected(int position) {
			// Unfortunately when TabHost changes the current tab, it kindly
			// also takes care of putting focus on it when not in touch mode.
			// The jerk.
			// This hack tries to prevent this from pulling focus out of our
			// ViewPager.
			TabWidget widget = mTabHost.getTabWidget();
			int oldFocusability = widget.getDescendantFocusability();
			widget.setDescendantFocusability(ViewGroup.FOCUS_BLOCK_DESCENDANTS);
			mTabHost.setCurrentTab(position);
			widget.setDescendantFocusability(oldFocusability);
		}

		@Override
		public void onPageScrollStateChanged(int arg0) {
		}
	}

	@Override
	public void onCreateRoomDialogConfirmed(String roomName) {
		startService(ChatService.createRoomCreateIntent(this, roomName));
	}

	@Override
	public void onEnterRoomAction(String roomId) {
		if (findViewById(R.id.chat_container) != null) {
			mChatFragment = new ChatFragment();

			Bundle arguments = new Bundle();
			arguments.putString(ChatFragment.ARGUMENT_ROOM_ID, roomId);

			mChatFragment.setArguments(arguments);

			FragmentManager fragmentManager = getSupportFragmentManager();
			fragmentManager.beginTransaction()
					.replace(R.id.chat_container, mChatFragment).commit();
		} else {
			startActivity(ChatActivity.createChatIntent(
					getApplicationContext(), roomId));
		}
	}

	@Override
	public void onRoomToggleFavoriteAction(long _id, boolean currentlyFavorite) {
		ContentValues values = new ContentValues();

		values.put(
				RoomsContentProvider.ALL_COLUMNS[RoomsContentProvider.FAVORITE_COLUMN_INDEX],
				(!currentlyFavorite ? 1.0f : 0.0f));

		getContentResolver()
				.update(RoomsContentProvider.CONTENT_URI,
						values,
						RoomsContentProvider.ALL_COLUMNS[RoomsContentProvider.ID_COLUMN_INDEX]
								+ "=?", new String[] { Long.toString(_id) });
	}

	@Override
	public void onRoomShare(long id) {
		Room room = ContentUtils.getRoomById(this, id);

		Intent emailIntent = new Intent(android.content.Intent.ACTION_SEND);

		emailIntent.putExtra(android.content.Intent.EXTRA_SUBJECT,
				getString(R.string.email_title, room.name));
		emailIntent.setType("plain/text");
		emailIntent.putExtra(
				android.content.Intent.EXTRA_TEXT,
				getString(R.string.email_content, room.name,
						"http://netchatdemo.appspot.com/rooms/" + room.room_id
								+ "?roomName=" + Uri.encode(room.name)));
		startActivity(emailIntent);
	}

	@Override
	public void onRoomDelete(long id) {
		startService(ChatService.createRoomDeleteIntent(this, id));
	}

	public static Intent createEnterRoomIntent(Context context, String roomId) {
		Intent intent = new Intent(context, MainActivity.class);

		intent.putExtra(ROOM_ID_EXTRA, roomId);

		return intent;
	}

	@Override
	public void onRoomDelete() {
		if (mChatFragment != null) {
			getSupportFragmentManager().beginTransaction()
					.remove(mChatFragment).commit();
		}
	}
}
